package com.itheima.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.bean.Category;
import com.itheima.bean.Dish;
import com.itheima.bean.DishFlavor;
import com.itheima.bean.MyPage;
import com.itheima.dao.DishDao;
import com.itheima.dto.DishDto;
import com.itheima.service.CategoryService;
import com.itheima.service.DishFlavorService;
import com.itheima.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Transactional
public class DishServiceImpl implements DishService {
    @Autowired
    private DishFlavorService dishFlavorService;
    @Lazy
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private DishDao dishDao;
    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public List<DishDto> findAll(long id,Integer status) {
        //定义存储的键的值
        String key = "dish_" + id + status;
        //先在redis数据库查找是否有缓存，有换存则直接返回数据
        String s = (String) redisTemplate.opsForValue().get(key);
        if (s != null){
            return JSON.parseObject(s,List.class);
        }
        //判断是前端传来的，还是后台传过来的请求
        /*if (status==null) {
            //创建设置条件对象
            LambdaQueryWrapper<DishDto> qw = new LambdaQueryWrapper<>();
            //设置查询条件
            qw.eq(Dish::getCategoryId, id);
            //调用dao查询进行查询，返回查到的数据集合

            return dishDao.selectList(qw);
        }else {*/
            //进入这里就是前端发送过来的请求,创建条件查询对象
            LambdaQueryWrapper<Dish> qw1 = new LambdaQueryWrapper<>();
            //设置查询条件
            qw1.eq(Dish::getCategoryId, id);
            qw1.eq(status!=null,Dish::getStatus,status);
            List<DishDto> list = dishDao.selectList(qw1).stream().map((dish)->{
                //创建一个dishDto对象，将Dish对象的id传入DishDto对象中
                DishDto dishDto = new DishDto();
                //根据dish的categoryId为条件查询category的对象，获取分类名
                Category category = categoryService.findById(dish.getCategoryId());
                //根据dish的id为查询条件，查询指定的菜品口味为多少
                List<DishFlavor> dishFlavors = dishFlavorService.findByDishId(dish.getId());
                //查询的口味集合，和菜品分类名称，添加到DishDto对象中
                dishDto.setFlavors(dishFlavors);
                dishDto.setCategoryName(category.getName());
                //将dish接收的数据拷贝到dishDto对象中
                BeanUtils.copyProperties(dish,dishDto);
                return dishDto;
            }).collect(Collectors.toList());
            //执行mysql数据库的查询就表示，redis里面没有缓存，就先将获取的list集合转换为json字符串，存入redis
            //数据库中
            redisTemplate.opsForValue().set(key,JSON.toJSONString(list),24, TimeUnit.HOURS);
            return list;
        /*}*/

    }

    @Override
    public int add(DishDto dto) {
        //先添加菜品
        int row = dishDao.insert(dto);
        //设置这个口味属于哪一种菜
        int row2 = 0;
        //判断菜品是否添加成功，是否有上传菜品口味
        if (row > 0 && dto.getFlavors() !=null && dto.getFlavors().size() !=0){
            for (DishFlavor flavor : dto.getFlavors()) {
                //将菜品id赋值给口味的外键，知道是那个菜品的口味
                flavor.setDishId(dto.getId());
                row2 += dishFlavorService.add(flavor);
                //判断所有口味是否添加成功，成功则让row为1，失败则让row为0，返回添加菜品失败
                if (row2 == dto.getFlavors().size()){
                    row = 1;
                }else {
                    row = 0;
                }
            }
        }
        //判断是否添加成功菜品吗，携带的flavors是否为空
        return row;
    }

    @Override
    public /*IPage<Dish>*/IPage<DishDto> findAll(MyPage page) {

        IPage<Dish> ip = new Page<>(page.getPage(),page.getPageSize());
        //创建条件设置条件对象
        LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        //设置模糊查询条件
        qw.like(page.getName()!=null,Dish::getName,page.getName());
        //进行分页查询，获取IPage对象
        IPage<Dish> dishIPage = dishDao.selectPage(ip, qw);
        //获取当前页码数据集合
        List<Dish> list = dishIPage.getRecords();
        //将集合进行流的遍历,获取每一个集合中的dish对象
        List<DishDto> dishDtoList = list.stream().map((dish)->{
            //创建一个dishDto对象，将Dish对象的id传入DishDto对象中
            DishDto dishDto = new DishDto();
            //根据dish的categoryId为条件查询category的对象，获取分类名
            Category category = categoryService.findById(dish.getCategoryId());
            //根据dish的id为查询条件，查询指定的菜品口味为多少
            List<DishFlavor> dishFlavors = dishFlavorService.findByDishId(dish.getId());
            //查询的口味集合，和菜品分类名称，添加到DishDto对象中
            dishDto.setFlavors(dishFlavors);
            dishDto.setCategoryName(category.getName());
            //将dish接收的数据拷贝到dishDto对象中
            BeanUtils.copyProperties(dish,dishDto);
            return dishDto;
        }).collect(Collectors.toList());
        /*return dishIPage;*/

        //创建IPage的dishDto对象，设置
        IPage<DishDto> iPage = new Page<>();
        iPage.setRecords(dishDtoList);
        iPage.setTotal(dishIPage.getTotal());
        return iPage;
    }

    @Override
    public int update(DishDto dishDto) {
        //调用dao传入修改的对象进行修改
        int row = dishDao.updateById(dishDto);

        //获取口味的集合对象
        List<DishFlavor> list = dishDto.getFlavors();

        //判断是否更新成功,添加成功则，根据dish的id对口味进行删除
        if (row>0){
            int row2 = dishFlavorService.delete(dishDto.getId());
            //判断集合中有没有数据，集合长度不为0，有则表示有修改口味对口味进行删除然后添加，执行添加操作
            int row3 = 0;
            if (list !=null && list.size()!=0){
                //遍历集合，添加遍历出的每一个口味
                for (DishFlavor dishFlavor : list) {
                    //将dish的id添加到dishFlavor对象中
                    dishFlavor.setDishId(dishDto.getId());
                    //调用dishFlavor中的service层的方发进行添加口味
                     row3 += dishFlavorService.add(dishFlavor);
                }
                //判断口味是否添加成功，成功则把row赋值为1，失败则把row赋值为0
                row = row3==list.size() ? 1 : 0;
            }
        }
        return row;
    }

    @Override
    public int updateStatus(int status, List<Long> statusId) {
        //先判断status是否为1，为一则表示是启用请求，将传过来的id进行循环查询，然后将状态改为1，在在数据库进行修改
        /*LambdaQueryWrapper<Dish> qw = new LambdaQueryWrapper<>();
        qw.in(Dish::getId,statusId);
        List<Dish> list = dishDao.selectList(qw);*/

        //定义一个旗帜变量，记录影响行数，初始值为0
        int row = 0;

        if (status==1){
            int row2=0;
            for (Long dishId : statusId) {
                //获取要修改的对象，先进行查询，
                Dish dish = dishDao.selectById(dishId);
                dish.setStatus(1);
                //在根据id进行修改
                row2 +=dishDao.updateById(dish);
            }
            return row2 == statusId.size() ? 1 : 0;
        }
        //没走上面的if语句里面的代码则表示是停售，遍历传过来的id集合，先根据id进行查询，然后将status改为0，停售状态
        int row1 =0;
        for (Long dishId : statusId) {
            //获取要修改的对象，先进行查询，
            Dish dish = dishDao.selectById(dishId);
            dish.setStatus(0);
            //在根据id进行修改
            row1 += dishDao.updateById(dish);

        }
        return row1 == statusId.size() ? 1 : 0;
    }
}
